# -*- coding: utf-8 -*-
# @Time    : 2018/5/29 下午11:26
# @Author  : Lavn
# @Email   : 959875529@qq.com
# @File    : magicMethon2.py
# @Software: PyCharm


# 一般来说，一个描述器是一个有“绑定行为”的对象属性 (object attribute)，它的访问控制被描述器协议方法重写。
# 这些方法是 __get__(), __set__() , 和 __delete__() 。
# 有这些方法的对象叫做描述器。
#
# 默认对属性的访问控制是从对象的字典里面 (__dict__) 中获取 (get) , 设置 (set) 和删除 (delete) 。
# 举例来说， a.x 的查找顺序是, a.__dict__['x'] , 然后 type(a).__dict__['x'] , 然后找 type(a) 的父类 ( 不包括元类 (metaclass) ).
# 如果查找到的值是一个描述器, Python 就会调用描述器的方法来重写默认的控制行为。
# 这个重写发生在这个查找环节的哪里取决于定义了哪个描述器方法。
# 注意, 只有在新式类中时描述器才会起作用。在之前的篇节中已经提到新式类和旧式类的，有兴趣可以查看之前的篇节来看看，
# 至于新式类最大的特点就是所有类都继承自 type 或者 object 的类。

# 在面向对象编程时，如果一个类的属性有相互依赖的关系时，使用描述器来编写代码可以很巧妙的组织逻辑。
# 在 Django 的 ORM 中,models.Model中的 InterField 等字段, 就是通过描述器来实现功能的。

class User(object):
    def __init__(self, name='两点水', sex='男'):
        self.sex = sex
        self.name = name

    def __get__(self, obj, objtype):
        print('获取 name 值')
        return self.name

    def __set__(self, obj, val):
        print('设置 name 值')
        self.name = val

class MyClass(object):
    x = User('两点水', '男')
    y = 5

if __name__ == '__main__':
    c = User();
    print(c.sex)

    m = MyClass()
    print(m.x)

    print('\n')

    m.x = '三点水'
    print(m.x)

    print('\n')

    print(m.x)

    print('\n')

    print(m.y)



class Meter(object):
    def __init__(self, value=0.0):
        self.value = float(value)

    def __get__(self, instance, owner):
        return self.value

    def __set__(self, instance, value):
        self.value = float(value)


class Foot(object):
    def __get__(self, instance, owner):
        return instance.meter * 3.2808

    def __set__(self, instance, value):
        instance.meter = float(value) / 3.2808


class Distance(object):
    meter = Meter()
    foot = Foot()


if __name__ == '__main__':
    d = Distance()
    print(d.meter, d.foot)
    d.meter = 1
    print(d.meter, d.foot)
    d.meter = 2
    print(d.meter, d.foot)